package ${packageName}.controller;

import com.baomidou.mybatisplus.extension.service.IService;
import com.cecil.generate.model.Result;
import com.generate.domain.BaseEntity;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public abstract class BaseController<T extends BaseEntity, S extends IService<T>> {

    protected S service;

    public BaseController(S service) {
        this.service = service;
    }

    protected void outputExcel(HttpServletResponse response, String fileName) {
        output(response, fileName, "application/vnd.ms-excel;charset=UTF-8");
    }

    protected void outputPdf(HttpServletResponse response, String fileName) {
        output(response, fileName, "application/pdf;charset=UTF-8");
    }

    protected void outputFile(HttpServletResponse response, String fileName) {
        output(response, fileName, "application/octet-stream;charset=UTF-8");
    }

    protected void output(HttpServletResponse response, String fileName, String contentType) {
        response.setContentType(contentType);
        response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.addHeader("Pragma", "no-cache");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
    }

    @GetMapping(value = "/get/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<T> get(@PathVariable("id") Serializable id) {
        T t = service.getById(id);
        return Result.success(t);
    }

    @PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> add(@RequestBody @Valid T t) {
        service.save(t);
        return Result.success();
    }

    @PutMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> update(@RequestBody @Valid T t) {
        T exist = service.getById(t.getId());
        if (exist != null) {
            t.setVersion(exist.getVersion());
            service.updateById(t);
        }
        return Result.success();
    }

    @DeleteMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> delete(@RequestParam("id") Serializable id) {
        service.removeById(id);
        return Result.success();
    }
}